package com.fire.user.util.wx;

import java.util.*;
import java.util.concurrent.TimeUnit;

import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;

import com.fire.user.util.JkWxUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import com.fire.core.util.AjaxResult;
import com.fire.user.constants.ErrorCodeConstants;
import com.fire.user.model.WchatEntity;

import me.chanjar.weixin.common.util.StringUtils;

@Component
public class WxConfigUtil {
	private static Logger logger = Logger.getLogger(WxConfigUtil.class);

	@Autowired
	RedisTemplate redisTemplate;

	@Autowired
	HttpsUtil httpsUtil;

	@Value("${weChat.accessTokenUrl}")
	private String accessTokenUrl;

	@Value("${weChat.ticketUrl}")
	private String ticketUrl;

	@Value("${weChat.accessTokenTime}")
	private String accessTokenTime;

	@Value("${weChat.ticketTime}")
	private String ticketTime;
	
	@Value("${weChat.switch}")
	private String type;
	@Autowired
	private JkWxUtils jkWxUtils;

	public WchatEntity getWinXinEntity(String accessToken, String url, String appid, String secret) {
		WchatEntity wx = new WchatEntity();
		String access_token = null;
		String ticket = null;
		Map<String, String> ret = new HashMap<String, String>();
		if("1".equals(type)) {
    		AjaxResult result = jkWxUtils.getJKTicket();
    		if(ErrorCodeConstants.SUCCESS.equals(result.getStatus())) {
    			ticket = (String)result.getContext();
    		}
    	}else {
			access_token = getToken(accessToken, appid, secret);
			if (StringUtils.isBlank(access_token)) {
				return wx;
			}
			logger.info("access_token:" + access_token);
			
			ticket = queryTicket(access_token, "ticket");
			logger.info("ticket:" + ticket);
		}
		if (StringUtils.isBlank(ticket)) {
			return wx;
		}
		try {
			ret = Sign.sign(ticket, url);
			logger.info("ret:" + ret);
		} catch (Exception e) {
			logger.error("微信签名信息获取失败,appid:" + appid, e);
		}
		wx.setAccess_token(access_token);
		wx.setTicket(ret.get("jsapi_ticket"));
		wx.setSignature(ret.get("signature"));
		wx.setNoncestr(ret.get("nonceStr"));
		wx.setTimestamp(ret.get("timestamp"));
		return wx;
	}

	/*
	 * public Map<String, String> getSignature(String token,String url,String
	 * appid,String secret) { WchatEntity wx = new WchatEntity(); AccessToken
	 * accessToken = getAccessToken(token, appid,secret); String ticket =
	 * getTicket(accessToken.getAccessToken()); Map<String, String> ret =
	 * Sign.sign(ticket, url); return ret; }
	 */

	// 获取token
	private AccessToken getAccessToken(String token, String appid, String secret) {
		String access_token = "";
		String expire = "";
		JSONObject jsonObject = null;
		// String grant_type = "client_credential";// 获取access_token填写client_credential
		// 这个url链接地址和参数皆不能变
		String url = accessTokenUrl + "&appid=" + appid + "&secret=" + secret; // 访问链接

		AccessToken accessToken = new AccessToken();
		try {
			jsonObject = httpsUtil.httpsRequest(url, "GET", null);
			if (null != jsonObject) {
				try {
					accessToken.setAccessToken(jsonObject.getString("access_token"));
					accessToken.setExpiresin(jsonObject.getInteger("expires_in"));
					redisTemplate.opsForValue().set(token, accessToken.getAccessToken(),
							Integer.parseInt(accessTokenTime), TimeUnit.SECONDS);
				} catch (JSONException e) {
					access_token = null;
					// 获取token失败
					logger.error("获取token失败 errcode:" + jsonObject.getInteger("errcode") + "errmsg:"
							+ jsonObject.getString("errmsg"));

				}
			}

		} catch (Exception e) {
			logger.error("获取token失败 errcode:" + jsonObject.getInteger("errcode") + "errmsg:"
					+ jsonObject.getString("errmsg"));
		}

		return accessToken;

	}

	/**
	 * 去redis查询access_token是否过期，过期则重新获取否则就用缓存里面的*
	 * 
	 * @param access_token
	 * @param appid
	 * @param secret
	 * @return
	 */
	public String getToken(String access_token, String appid, String secret) {
		AccessToken accessToken = new AccessToken();
		Long oldDate = redisTemplate.getExpire(access_token);
		String oldoken;
		if (oldDate > 0) {
			logger.info("access_token没过期用的缓存。。。");
			oldoken = (String) redisTemplate.opsForValue().get(access_token);
			return oldoken;
		} else {
			logger.info("access_token过期重新获取了。。。");
			accessToken = getAccessToken(access_token, appid, secret);
			return accessToken.getAccessToken();
		}
	}

	/**
	 * 去redis查询ticket是否过期，过期则重新获取否则就用缓存里面的**
	 * 
	 * @param access_token
	 * @param ticketkey
	 * @return
	 */
	public String queryTicket(String access_token, String ticketkey) {
		String accessToken = null;
		Long oldDate = redisTemplate.getExpire(ticketkey);
		String oldoken;
		if (oldDate > 0) {
			logger.info("ticket没过期用的缓存。。。");
			oldoken = (String) redisTemplate.opsForValue().get(ticketkey);
			return oldoken;
		} else {
			logger.info("ticket过期重新获取了。。。");
			return getTicket(access_token);

		}
	}

	// 获取ticket
	private String getTicket(String access_token) {
		logger.info("此时的access_token:" + access_token);
		String ticket = null;
		String url = ticketUrl + "access_token=" + access_token + "&type=jsapi";// 这个url链接和参数不能变
		try {
			JSONObject jsonObject = httpsUtil.httpsRequest(url, "GET", null);
			logger.info("jsonObject:" + jsonObject);
			if (null != jsonObject) {
				try {
					ticket = jsonObject.getString("ticket");
					redisTemplate.opsForValue().set("ticket", jsonObject.getString("ticket"),
							Integer.parseInt(ticketTime), TimeUnit.SECONDS);
				} catch (JSONException e) {
					access_token = null;
					// 获取token失败
					logger.error("获取token失败 errcode:" + jsonObject.getInteger("errcode") + "errmsg:"
							+ jsonObject.getString("errmsg"));

				}
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
		return ticket;
	}
}